//
//  Encrypt.swift
//  casdon_swiftUI
//
//  Created by ww on 2025/4/3.
//
// 用于加密敏感数据，
// 随机生成32字节随机字符串作为AES密钥KEY，用RSA公钥加密AES密钥，然后用AES密钥加密数据。

import Foundation
import Security
import CommonCrypto
final class Encrypt {
    // 公钥 应当存入钥匙串
    private let pemPublicKey = EnvironmentConfig.shared.current.REQUEST_PUBLICKEY
    
    private var aesKey: Data?

    static let shared = Encrypt()

    /// 禁止使用init创建对象
    private init() {}

    /// 加密数据,返回加密后的base64字符串
    func encrypt(_ text: String) -> String? {
        guard let data = text.data(using: .utf8) else { return nil }
        guard let aesKey = aesKey else {
         
            Logger.log(.error, message: "AES密钥为空", tag: LogTag.encrypt)
            return nil
        }
        Logger.log(.debug, message: "准备AES加密", tag: LogTag.encrypt)
        Logger.log(.debug, message: "待加密字符串：\(text)", tag: LogTag.encrypt)
        let keyLength = aesKey.count
            guard keyLength == kCCKeySizeAES128 || keyLength == kCCKeySizeAES192 || keyLength == kCCKeySizeAES256 else {
                return nil // key 长度不合法
            }

            let bufferSize = data.count + kCCBlockSizeAES128
            var buffer = Data(count: bufferSize)
            var numBytesEncrypted: size_t = 0

            let cryptStatus = buffer.withUnsafeMutableBytes { bufferBytes in
                data.withUnsafeBytes { dataBytes in
                    aesKey.withUnsafeBytes { keyBytes in
                        CCCrypt(CCOperation(kCCEncrypt),
                                CCAlgorithm(kCCAlgorithmAES),
                                CCOptions(kCCOptionPKCS7Padding | kCCOptionECBMode),
                                keyBytes.baseAddress, keyLength,
                                nil, // ECB 模式，不需要 IV
                                dataBytes.baseAddress, data.count,
                                bufferBytes.baseAddress, bufferSize,
                                &numBytesEncrypted)
                    }
                }
            }
            if cryptStatus == kCCSuccess {
                let encryptedText = buffer.prefix(numBytesEncrypted).base64EncodedString()
                Logger.log(.debug, message: "加密成功：\(encryptedText)", tag: LogTag.encrypt)
                return encryptedText
            }

        Logger.log(.error, message: "加密失败", tag: LogTag.encrypt)
        return nil
    }
    
    func rsaEncryptRaw() -> String? {
        Logger.log(.debug, message: "准备RSA加密", tag: LogTag.encrypt)
        guard let publickey = publicKey() else {
            Logger.log(.error, message: "加载rsa公钥失败", tag: LogTag.encrypt)
            return nil
        }
        guard let base64Data = aesKey?.base64EncodedString().data(using: .utf8) else {
            Logger.log(.error, message: "加载aes密钥失败", tag: LogTag.encrypt)
            return nil
        }
        
        let algorithm: SecKeyAlgorithm = .rsaEncryptionPKCS1
        guard SecKeyIsAlgorithmSupported(publickey, .encrypt, algorithm) else {
            Logger.log(.error, message: "加密算法不被支持", tag: LogTag.encrypt)
            return nil
        }

        var error: Unmanaged<CFError>?
        guard let encrypted = SecKeyCreateEncryptedData(publickey,
                                                        algorithm,
                                                        base64Data as CFData,
                                                        &error) as Data? else {
            Logger.log(.error, message: "加密AES密钥失败: \(error!.takeRetainedValue())", tag: LogTag.encrypt)
            return nil
        }
        Logger.log(.debug, message: "加密后的密钥：\(encrypted.base64EncodedString())", tag: LogTag.encrypt)
        return encrypted.base64EncodedString()
    }
    
    func generateAESKey(){
        let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        let str = String((0..<32).map { _ in characters.randomElement()! })
        
        aesKey = str.data(using: .utf8)
        guard let key = aesKey else{
            Logger.log(.error, message: "生成AES32位密钥失败", tag: LogTag.encrypt)
            return
        }
        Logger.log(.debug, message: "生成AES32位密钥原始值: \(str)", tag: LogTag.encrypt)
        Logger.log(.debug, message: "生成AES32位密钥base64值: \(key.base64EncodedString())", tag: LogTag.encrypt)
    }
    
    /// 将 PEM 格式的公钥字符串转换为 SecKey
    private func publicKey() -> SecKey? {
        // 1. 去掉 PEM 标记和换行符
        let lines = pemPublicKey.components(separatedBy: "\n")
        let base64String = lines.filter { !$0.contains("-----") }
            .joined()

        // 2. 解码 Base64 得到公钥数据
        guard let keyData = Data(base64Encoded: base64String) else {
            Logger.log(.error, message: "Base64 解码失败", tag: LogTag.encrypt)
            return nil
        }

        // 3. 设置公钥属性
        let keyDict: [String: Any] = [
            kSecAttrKeyType as String: kSecAttrKeyTypeRSA, // RSA 类型
            kSecAttrKeyClass as String: kSecAttrKeyClassPublic, // 公钥
        ]

        // 4. 调用 SecKeyCreateWithData 创建 SecKey 对象
        var error: Unmanaged<CFError>?
        guard let secKey = SecKeyCreateWithData(keyData as CFData,
                                                keyDict as CFDictionary,
                                                &error)
        else {
            if let error = error {
                Logger.log(.error, message: "SecKeyCreateWithData 失败: \(error.takeRetainedValue())", tag: LogTag.encrypt)
            }
            return nil
        }

        return secKey
    }
}
